/*
 * @Author: january.cjy
 * @Date: 2021-11-01 16:14:11
 * @Last Modified by: january.cjy
 * @Last Modified time: 2021-11-05 20:55:44
 */
#include <Database.h>
#include <OUT.h>

namespace cmg {
bool Connection::connect() { return true; }

bool Connection::insertToVtables(string &module, string &vtable,
                                 unsigned int offset_to_top,
                                 string &virtual_function) {
  string InsertInstruction =
      "INSERT INTO Vtables (module,vtable,offset_to_top,virtual_function) "
      "VALUES (\"";
  InsertInstruction += module + "\",\"";
  InsertInstruction += vtable + "\",";
  InsertInstruction += to_string(offset_to_top) + ",\"";
  InsertInstruction += virtual_function + "\")";
  OUT_ << "Mysql operation: " << InsertInstruction << "\n";

#if CONNECTION_ON_ == 0
  return true;
#endif

  int res = mysql_query(const_cast<MYSQL *>(&conn), InsertInstruction.c_str());
  // ERRS_.changeColor(llvm::raw_ostream::RED);
  if (res) {
    ERRS_.changeColor(llvm::raw_ostream::RED);
    ERRS_ << "insert into Vtables fail - " << res << "\n";
    ERRS_.resetColor();
    return false;
  } else {
    // ERRS_.changeColor(llvm::raw_ostream::YELLOW);
    // ERRS_ << "insert into Vtables success - " << res << "\n";
    // ERRS_.resetColor();
    return true;
  }
}

bool Connection::insertToTypeMetadata(string &type_metadata, string &vtable,
                                      unsigned int offset) {
  string InsertInstruction =
      "INSERT INTO TypeMetadata (type_metadata,vtable,offset) "
      "VALUES (\"";
  InsertInstruction += type_metadata + "\",\"";
  InsertInstruction += vtable + "\",";
  InsertInstruction += to_string(offset) + ")";
  OUT_ << "Mysql operation: " << InsertInstruction << "\n";

#if CONNECTION_ON_ == 0
  return true;
#endif

  int res = mysql_query(const_cast<MYSQL *>(&conn), InsertInstruction.c_str());
  // ERRS_.changeColor(llvm::raw_ostream::RED);
  if (res) {
    ERRS_.changeColor(llvm::raw_ostream::RED);
    ERRS_ << "insert into TypeMetadata fail - " << res << "\n";
    ERRS_.resetColor();
    return false;
  } else {
    // ERRS_.changeColor(llvm::raw_ostream::YELLOW);
    // ERRS_ << "insert into TypeMetadata success - " << res << "\n";
    // ERRS_.resetColor();
    return true;
  }
}

bool Connection::insertToVitualCall(string &module, string &user_symbol,
                                    string &type_metadata,
                                    unsigned int offset) {
  string InsertInstruction =
      "INSERT INTO VirtualCall (module,user_symbol,type_metadata,offset) "
      "VALUES (\"";
  InsertInstruction += module + "\",\"";
  InsertInstruction += user_symbol + "\",\"";
  InsertInstruction += type_metadata + "\",";
  InsertInstruction += to_string(offset) + ")";
  OUT_ << "Mysql operation: " << InsertInstruction << "\n";

#if CONNECTION_ON_ == 0
  return true;
#endif

  int res = mysql_query(const_cast<MYSQL *>(&conn), InsertInstruction.c_str());
  // ERRS_.changeColor(llvm::raw_ostream::RED);
  if (res) {
    ERRS_.changeColor(llvm::raw_ostream::RED);
    ERRS_ << "insert into VirtualCall fail - " << res << "\n";
    ERRS_.resetColor();
    return false;
  } else {
    // ERRS_.changeColor(llvm::raw_ostream::YELLOW);
    // ERRS_ << "insert into VirtualCall success - " << res << "\n";
    // ERRS_.resetColor();
    return true;
  }
  return true;
}

bool Connection::insertToSymbolDefinition(string &module, string &symbol,
                                          unsigned int symbol_tag,
                                          string linkage, string visibility) {
  string InsertInstruction = "INSERT INTO SymbolDefinition "
                             "(module,symbol,symbol_tag,linkage,visibility) "
                             "VALUES (\"";
  InsertInstruction += module + "\",\"";
  InsertInstruction += symbol + "\",";
  InsertInstruction += to_string(symbol_tag) + ",\"";
  InsertInstruction += linkage + "\",\"";
  InsertInstruction += visibility + "\")";
  OUT_ << "Mysql operation: " << InsertInstruction << "\n";

#if CONNECTION_ON_ == 0
  return true;
#endif

  int res = mysql_query(const_cast<MYSQL *>(&conn), InsertInstruction.c_str());
  // ERRS_.changeColor(llvm::raw_ostream::RED);
  if (res) {
    ERRS_.changeColor(llvm::raw_ostream::RED);
    ERRS_ << "insert into SymbolDefinition fail - " << res << "\n";
    ERRS_.resetColor();
    return false;
  } else {
    // ERRS_.changeColor(llvm::raw_ostream::YELLOW);
    // ERRS_ << "insert into SymbolDefinition success - " << res << "\n";
    // ERRS_.resetColor();
    return true;
  }
  return true;
}

bool Connection::insertToSymbolUse(string &module, string &user_symbol,
                                   string &used_symbol) {
  string InsertInstruction =
      "INSERT INTO SymbolUse (module,user_symbol,used_symbol) "
      "VALUES (\"";
  InsertInstruction += module + "\",\"";
  InsertInstruction += user_symbol + "\",\"";
  InsertInstruction += used_symbol + "\")";
  OUT_ << "Mysql operation: " << InsertInstruction << "\n";

#if CONNECTION_ON_ == 0
  return true;
#endif

  int res = mysql_query(const_cast<MYSQL *>(&conn), InsertInstruction.c_str());
  // ERRS_.changeColor(llvm::raw_ostream::RED);
  if (res) {
    ERRS_.changeColor(llvm::raw_ostream::RED);
    ERRS_ << "insert into SymbolUse fail - " << res << "\n";
    ERRS_.resetColor();
    return false;
  } else {
    // ERRS_.changeColor(llvm::raw_ostream::YELLOW);
    // ERRS_ << "insert into SymbolUse success - " << res << "\n";
    // ERRS_.resetColor();
    return true;
  }
  return true;
}

} // namespace cmg